package com.ciwong.epaper.widget.evaluate;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.RelativeLayout;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;

/**
 * 这是一个波纹效果布局,该布局中默认添加了不可见的圆形的视图,启动动画时会启动缩放、颜色渐变动画使得产生波纹效果.
 * 这些动画都是无限循环的,并且每个View的动画之间都有时间间隔，这些时间间隔就会导致视图有大有小，从而产生波纹的效果.
 *
 * @author sugy
 */
public class RippleLayout extends RelativeLayout
{

    private int mRippleColor = Color.parseColor("#CFF0CA");

    private float mRippleRadius = 70;// 波形宽度

    private int mAnimDuration = 2500;// 时长

    private int mRippleViewNums = 3;// 波形数量

    private float mRippleScale = 3.5f;// 放大倍数

    private int mAnimDelay;

    private boolean animationRunning = false;

    /**
     *
     */
    private Paint mPaint = new Paint();

    /**
     * 动画集,执行缩放、alpha动画,使得背景色渐变
     */
    private AnimatorSet mAnimatorSet = new AnimatorSet();

    /**
     * 动画列表,保存几个动画
     */
    private ArrayList<Animator> mAnimatorList = new ArrayList<Animator>();

    /**
     * RippleView Params
     */
    private LayoutParams mRippleViewParams;

    /**
     * @param context
     */
    public RippleLayout(Context context)
    {
        super(context);
        init(context, null);
    }

    public RippleLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init(context, attrs);
    }

    public RippleLayout(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(final Context context, final AttributeSet attrs)
    {
        if (isInEditMode())
        {
            return;
        }

        initPaint();
        initRippleViewLayoutParams();
        generateRippleViews();

    }

    private void initPaint()
    {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(mRippleColor);
    }

    private void initRippleViewLayoutParams()
    {
        // ripple view的大小为 半径 + 笔宽的两倍
        int rippleSide = (int) (2 * mRippleRadius);
        mRippleViewParams = new LayoutParams(rippleSide, rippleSide);
        // 居中显示
        mRippleViewParams.addRule(CENTER_IN_PARENT, TRUE);
    }

    /**
     * 计算每个RippleView之间的动画时间间隔,从而产生波纹效果
     */
    private void calculateAnimDelay()
    {
        mAnimDelay = mAnimDuration / mRippleViewNums;
    }

    /**
     * 初始化RippleViews，并且将动画设置到RippleView上,使之在x, y不断扩大,并且背景色逐渐淡化
     */
    private void generateRippleViews()
    {

        calculateAnimDelay();
        initAnimSet();
        // 添加RippleView
        for (int i = 0; i < mRippleViewNums; i++)
        {
            RippleView rippleView = new RippleView(getContext());
            addView(rippleView, mRippleViewParams);
            // 添加动画
            addAnimToRippleView(rippleView, i);
        }

        // x, y, alpha动画一块执行
        mAnimatorSet.playTogether(mAnimatorList);
    }

    private void initAnimSet()
    {
        mAnimatorSet.setDuration(mAnimDuration);
        mAnimatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
    }

    /**
     * 为每个RippleView添加动画效果,并且设置动画延时,每个视图启动动画的时间不同,就会产生波纹
     *
     * @param rippleView
     * @param i
     *            视图所在的索引
     */
    private void addAnimToRippleView(RippleView rippleView, int i)
    {

        // x轴的缩放动画
        final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(rippleView,
                "scaleX", 1.0f, mRippleScale);
        scaleXAnimator.setRepeatCount(ObjectAnimator.INFINITE);
        scaleXAnimator.setRepeatMode(ObjectAnimator.RESTART);
        scaleXAnimator.setStartDelay(i * mAnimDelay);
        scaleXAnimator.setDuration(mAnimDuration);
        mAnimatorList.add(scaleXAnimator);

        // y轴的缩放动画
        final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(rippleView,
                "scaleY", 1.0f, mRippleScale);
        scaleYAnimator.setRepeatMode(ObjectAnimator.RESTART);
        scaleYAnimator.setRepeatCount(ObjectAnimator.INFINITE);
        scaleYAnimator.setStartDelay(i * mAnimDelay);
        scaleYAnimator.setDuration(mAnimDuration);
        mAnimatorList.add(scaleYAnimator);

        // 颜色的alpha渐变动画
        final ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rippleView,
                "alpha", 1.0f, 0f);
        alphaAnimator.setRepeatMode(ObjectAnimator.RESTART);
        alphaAnimator.setRepeatCount(ObjectAnimator.INFINITE);
        alphaAnimator.setDuration(mAnimDuration);
        alphaAnimator.setStartDelay(i * mAnimDelay);
        mAnimatorList.add(alphaAnimator);
    }

    public void startRippleAnimation()
    {
        if (!isRippleAnimationRunning())
        {
            makeRippleViewsVisible();
            mAnimatorSet.start();
            animationRunning = true;
        }
    }

    private void makeRippleViewsVisible()
    {
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++)
        {
            View childView = this.getChildAt(i);
            if (childView instanceof RippleView)
            {
                childView.setVisibility(VISIBLE);
            }
        }
    }

    public void stopRippleAnimation()
    {
        if (isRippleAnimationRunning())
        {
            mAnimatorSet.end();
            animationRunning = false;
        }
    }

    public boolean isRippleAnimationRunning()
    {
        return animationRunning;
    }

    /**
     * RippleView产生波纹效果, 默认不可见,当启动动画时才设置为可见
     *
     * @author mrsimple
     */
    private class RippleView extends View
    {

        public RippleView(Context context)
        {
            super(context);
            this.setVisibility(View.INVISIBLE);
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            int radius = (Math.min(getWidth(), getHeight())) / 2;
            canvas.drawCircle(radius, radius, radius, mPaint);
        }
    }
}
